package com.example.auth.controller;

import com.example.auth.annotation.RequireRole;
import com.example.auth.dto.ChangePasswordRequest;
import com.example.auth.entity.User;
import com.example.auth.service.UserService;
import com.example.auth.util.JwtUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/auth")
public class AuthController {

    private static final Logger logger = LoggerFactory.getLogger(AuthController.class);

    @Autowired
    private UserService userService;

    @Autowired
    private JwtUtil jwtUtil;

    @PostMapping("/register")
    public ResponseEntity<?> register(@RequestBody Map<String, String> request) {
        String username = request.get("username");
        String password = request.get("password");
        String realName = request.get("realName");
        String nickname = request.get("nickname");
        String email = request.get("email");
        String phone = request.get("phone");

        try {
            User user = userService.register(username, password, realName, nickname, email, phone);
            return ResponseEntity.ok(Map.of(
                    "message", "Registration successful", // Registration successful
                    "user", Map.of(
                            "id", user.getId(),
                            "username", user.getUsername()
                    )
            ));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(Map.of(
                    "message", e.getMessage()
            ));
        }
    }

    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody Map<String, String> request) {
        String username = request.get("username");
        String password = request.get("password");

        logger.info("Login attempt for username: {}", username);

        User user = userService.findByUsername(username);
        if (user == null) {
            logger.warn("User not found: {}", username);
            return ResponseEntity.badRequest().body(Map.of(
                    "message", "Incorrect username or password" // Incorrect username or password
            ));
        }

        logger.info("User found: {}, stored password format: {}", username, 
            user.getPassword().length() > 10 ? user.getPassword().substring(0, 10) + "..." : user.getPassword());

        if (!userService.validatePassword(user, password)) {
            logger.warn("Password validation failed for user: {}", username);
            return ResponseEntity.badRequest().body(Map.of(
                    "message", "Incorrect username or password" // Incorrect username or password
            ));
        }

        // Check user status, prevent disabled users from logging in
        if ("inactive".equals(user.getStatus())) {
            logger.warn("Login attempt for inactive user: {}", username);
            return ResponseEntity.badRequest().body(Map.of(
                    "message", "Account is disabled, please contact the administrator" // Account is disabled, please contact the administrator
            ));
        }

        logger.info("Login successful for user: {}", username);

        // Use the new generateToken method, including the user ID
        String token = jwtUtil.generateToken(username, user.getId());

        Map<String, Object> response = new HashMap<>();
        response.put("token", token);

        Map<String, Object> userData = new HashMap<>();
        userData.put("id", user.getId());
        userData.put("username", user.getUsername());
        userData.put("avatar", user.getAvatar());
        userData.put("roles", user.getRoles().stream().map(role -> role.getName()).toList());

        userData.put("realName", user.getRealName());
        userData.put("nickname", user.getNickname());
        userData.put("email", user.getEmail());
        userData.put("phone", user.getPhone());
        userData.put("bio", user.getBio());

        response.put("user", userData);

        return ResponseEntity.ok(response);
    }

    @GetMapping("/info")
    @RequireRole("USER")
    public ResponseEntity<?> getUserInfo(@RequestHeader("Authorization") String auth) {
        String token = auth.substring(7);
        String username = jwtUtil.getUsernameFromToken(token);
        User user = userService.findByUsername(username);

        Map<String, Object> userData = new HashMap<>();
        userData.put("id", user.getId());
        userData.put("username", user.getUsername());
        userData.put("avatar", user.getAvatar());
        userData.put("roles", user.getRoles().stream().map(role -> role.getName()).toList());

        userData.put("realName", user.getRealName());
        userData.put("nickname", user.getNickname());
        userData.put("email", user.getEmail());
        userData.put("phone", user.getPhone());
        userData.put("bio", user.getBio());

        return ResponseEntity.ok(Map.of(
                "user", userData
        ));
    }

    @PostMapping("/change-password")
    @RequireRole("USER")
    public ResponseEntity<?> changePassword(
            @RequestHeader("Authorization") String auth,
            @RequestBody ChangePasswordRequest request
    ) {
        try {
            String token = auth.substring(7);
            String username = jwtUtil.getUsernameFromToken(token);
            User user = userService.findByUsername(username);

            userService.changePassword(user, request.getCurrentPassword(), request.getNewPassword());

            return ResponseEntity.ok(Map.of(
                    "message", "Password changed successfully" // Password changed successfully
            ));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(Map.of(
                    "message", e.getMessage()
            ));
        }
    }

    @GetMapping("/admin")
    @RequireRole("ADMIN")
    public ResponseEntity<?> adminOnly() {
        return ResponseEntity.ok(Map.of(
                "message", "This information can only be seen by administrators" // This information can only be seen by administrators
        ));
    }
}